home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / STRINGS / SHLNGST1 / SHLNGSTR.PAS < prev    next >
Pascal/Delphi Source File  |  1991-02-19  |  41KB  |  1,291 lines

  1. {$R-,V-}
  2. unit ShLngStr;
  3.  
  4.  
  5.   {==========================================================================}
  6.               INTERFACE
  7.   {==========================================================================}
  8.  
  9. uses
  10.   TpInline,
  11.   TpString,
  12.   TpMemChk;
  13.  
  14.   {========== DECLARATIONS ==================================================}
  15.  
  16. const
  17.   MaxLongString = 65517; {Maximum length of LongString.}
  18.   NotFound = 0;          {Returned by the Pos functions if substring not found}
  19.   RingSize : byte = 25;
  20.  
  21. type
  22.   LongStringType  = record
  23.                       Length,
  24.                       dLength : word;
  25.                       lsData  : array[1..1] of char;
  26.                       end;
  27.   LongString      = ^LongStringType;
  28.   lsCompType      = (Less, Equal, Greater);
  29.  
  30.   {========== MEMORY MANAGEMENT =============================================}
  31.  
  32. function lsInit(var A  : LongString; L : word)  : boolean;
  33.   {"Declares" a LongString of maximum declared length L and establishes
  34.    space for it on the heap. Returns false if L is greater than
  35.    MaxLongString.}
  36.  
  37. procedure lsDispose(var A : LongString);
  38.   {-Dispose of A, releasing its heap space}
  39.  
  40.   {========== GENERAL HOUSEKEEPING ==========================================}
  41.  
  42. function lsComp(A1, A2 : LongString) : lsCompType;
  43.   {-Compares A1 to A2, returning LESS, EQUAL, or GREATER}
  44.  
  45. function lsCount(A, Obj : LongString):  word;
  46. function lsCountStr(A : LongString; Obj : string) : word;
  47.   {-Returns the number of occurrences of Obj in A}
  48.  
  49. function lsCountUC(A, Obj : LongString):  word;
  50. function lsCountStrUC(A : LongString; Obj : string) : word;
  51.   {-Returns the number of occurrences of Obj in A}
  52.   { The search is not CASE SENSITIVE.}
  53.  
  54. function lsLength(A : LongString) : word;
  55.   {-Return the length of a LongString. A must have been lsInited}
  56.  
  57. function lsPos(Obj, A : LongString) : word;
  58. function lsPosStr(Obj : string; A : LongString) : word;
  59.   {-Return the position of Obj in A, returning NotFound if not found}
  60.  
  61. function lsPosUC(Obj, A : LongString) : word;
  62. function lsPosStrUC(Obj : string; A : LongString) : word;
  63.   {-Return the position of Obj in A, returning NotFound if not found.
  64.    The search is not CASE SENSITIVE.}
  65.  
  66. function lsSizeOf(A : LongString) : word;
  67.   {-Returns the total heap space required for A. A must have been lsInited}
  68.  
  69.   {========== LONGSTRING TRANSFER (ASSIGNMENT) ==============================}
  70.  
  71. procedure lsTransfer(A, B : LongString);
  72.   {Transfers the contents of A into B}
  73.   {NOTE: B^ := A^ yields unpredictable results. DO NOT USE!
  74.  
  75.   {========== STRING <-> LONGSTRING TYPE CONVERSION =========================}
  76.  
  77. function lsLongString2Str(A : LongString) : string;
  78.   {-Convert LongString to Turbo string, truncating if longer than 255 chars}
  79.  
  80. procedure lsStr2LongString(S : string; A : LongString);
  81. function lsStr2LongStringF(S : string)  : LongString;
  82.   {-Convert a Turbo string into a LongString}
  83.  
  84.   {========== MANIPULATING LONGSTRINGS, STRINGS =============================}
  85.  
  86. procedure lsConcat(A, B, C : LongString);
  87. function lsConcatF(A, B : LongString) : LongString;
  88.   {-Concatenate two LongString strings, returning a third}
  89.  
  90. procedure lsConcatStr2Ls(A : LongString; S : string; C : LongString);
  91. function lsConcatStr2LsF(A : LongString; S : string)  : LongString;
  92.   {-Concatenate a string to a LongString, returning a new LongString}
  93.  
  94. procedure lsConcatLs2Str(S : string; A : LongString; C : LongString);
  95. function lsConcatLs2StrF(S : string; A : LongString)  : LongString;
  96.   {-Concatenate a LongString to a string, returning a new LongString}
  97.  
  98.   {========== SUBSTRINGS OF LONGSTRINGS, STRINGS ============================}
  99.  
  100. procedure lsCopy(A  : LongString; Start, Len  : word; B : LongString);
  101. function lsCopyF(A  : LongString; Start, Len  : word)  : LongString;
  102.   {-Return a long substring of A. Note Start=1 for first char in A}
  103.  
  104. procedure lsDelete(A : LongString; Start, Len : word; B : LongString);
  105. function lsDeleteF(A : LongString; Start, Len  : word) : LongString;
  106.   {-Delete Len characters of A, starting at position Start}
  107.  
  108. procedure lsInsert(A, Obj : LongString; Start : word; B : LongString);
  109. function lsInsertF(A, Obj : LongString; Start : word) : LongString;
  110.   {-Insert LongString Obj into A at position Start returning a new LongString}
  111.  
  112. procedure lsInsertStr(A : LongString; Obj : string;
  113.                       Start : word; B : LongString);
  114. function lsInsertStrF(A : LongString; Obj : string;
  115.                       Start : word) : LongString;
  116.   {-Insert string Obj into A at position Start returning a new LongString}
  117.  
  118. type
  119.   DelimSetType  = set of char;
  120. const
  121.   DelimSet  : DelimSetType = [#0..#32];
  122.  
  123. procedure lsGetNext(LS1, LS2  : LongString);
  124. function lsGetNextF(LS1 : LongString) : LongString;
  125. procedure lsGetNextStr(LS1  : LongString; var S2  : string);
  126. function lsGetNextStrF(LS1  : LongString) : string;
  127.   {-Returns the next substring of LS1 which is delimited by a member
  128.     of DelimSet.)
  129.  
  130.   {========== LONGSTRING TRANSFORMATIONS ====================================}
  131.  
  132. procedure lsCenter(A : LongString; Width : word; B : LongString);
  133. function lsCenterF(A : LongString; Width : word)  : LongString;
  134.   {-Return a LongString centered in a LongString of blanks with specified
  135.     width}
  136.  
  137. procedure lsCenterCh(A : LongString; Ch : Char; Width : word; B : LongString);
  138. function lsCenterChF(A : LongString; Ch : Char; Width : word) : LongString;
  139.   {-Return a LongString centered in a LongString of Ch with specified width}
  140.  
  141. procedure lsCharStr(Ch : Char; Len : word; A : LongString);
  142. function lsCharStrF(Ch : Char; Len : word) : LongString;
  143.   {-Return a LongString of length Len filled with Ch}
  144.  
  145. procedure lsLeftPad(A : LongString; Len : word; B : LongString);
  146. function lsLeftPadF(A : LongString; Len : word) : LongString;
  147.   {-Left-pad the LongString in A to length Len with blanks, returning
  148.     a new LongString}
  149.  
  150. procedure lsLeftPadCh(A : LongString; Ch : Char; Len : word; B : LongString);
  151. function lsLeftPadChF(A : LongString; Ch : Char; Len : word)  : LongString;
  152.   {-Left-pad the LongString in A to length Len with Ch, returning a new
  153.     LongString}
  154.  
  155. procedure lsLocase(A, B : LongString);
  156. function lsLocaseF(A  : LongString) : LongString;
  157.   {-Lowercase the LongString in A, returning a new LongString}
  158.  
  159. procedure lsPad(A : LongString; Len : word; B : LongString);
  160. function lsPadF(A : LongString; Len : word) : LongString;
  161.   {-Right-pad the LongString in A to length Len with blanks, returning
  162.     a new LongString}
  163.  
  164. procedure lsPadCh(A : LongString; Ch : Char; Len : word; B : LongString);
  165. function lsPadChF(A : LongString; Ch : Char; Len : word)  : LongString;
  166.   {-Right-pad the LongString in A to length Len with Ch, returning
  167.     a new LongString}
  168.  
  169. procedure lsTrim(A, B : LongString);
  170. function lsTrimF(A  : LongString) : LongString;
  171.   {-Return a LongString with leading and trailing white space removed}
  172.  
  173. procedure lsTrimLead(A, B : LongString);
  174. function lsTrimLeadF(A  : LongString): LongString;
  175.   {-Return a LongString with leading white space removed}
  176.  
  177. procedure lsTrimTrail(A, B : LongString);
  178. function lsTrimTrailF(A : LongString) : LongString;
  179.   {-Return a LongString with trailing white space removed}
  180.  
  181. procedure lsUpcase(A, B : LongString);
  182. function lsUpcaseF(A  : LongString) : LongString;
  183.   {-Uppercase the LongString in A, returning a new LongString}
  184.  
  185.   {========== GLOBAL PROCESSING =============================================}
  186.  
  187. procedure lsDelAll(A, Obj, B : LongString);
  188. function lsDelAllF(A, Obj : LongString):  LongString;
  189. procedure lsDelAllStr(A : LongString; Obj : string; B : LongString);
  190. function lsDelAllStrF(A : LongString; Obj : string) : LongString;
  191.   {-Deletes all occurrences of Obj in A}
  192.  
  193. procedure lsDelAllUC(A, Obj, B : LongString);
  194. function lsDelAllUCF(A, Obj : LongString):  LongString;
  195. procedure lsDelAllStrUC(A : LongString; Obj : string; B : LongString);
  196. function lsDelAllStrUCF(A : LongString; Obj : string) : LongString;
  197.   {-Deletes all occurrences of Obj in A}
  198.   { The search is not CASE SENSITIVE.}
  199.  
  200. procedure lsRepAll(A, Obj, Obj1, B : LongString);
  201. function lsRepAllF(A, Obj, Obj1 : LongString):  LongString;
  202. procedure lsRepAllStr(A : LongString; Obj, Obj1 : string; B : LongString);
  203. function lsRepAllStrF(A : LongString; Obj, Obj1 : string) : LongString;
  204.   {-Replaces all occurrences of Obj in A with Obj1}
  205.  
  206. procedure lsRepAllUC(A, Obj, Obj1, B : LongString);
  207. function lsRepAllUCF(A, Obj, Obj1 : LongString):  LongString;
  208. procedure lsRepAllStrUC(A : LongString; Obj, Obj1 : string; B : LongString);
  209. function lsRepAllStrUCF(A : LongString; Obj, Obj1 : string) : LongString;
  210.   {-Replaces all occurrences of Obj in A with Obj1}
  211.   { The search is not CASE SENSITIVE.}
  212.  
  213.   {========== INPUT / OUTPUT ================================================}
  214.  
  215. procedure lsReadLn(var F : Text; A : LongString);
  216.   {-Read a LongString from text file}
  217.  
  218. procedure lsWriteLn(var F : Text; A : LongString);
  219.   {-Write a LongString to text file}
  220.  
  221. procedure lsIon;
  222.   {-Has the same effect with respect to lsReadLn, lsWriteLn as the $I+
  223.     compiler has with respect to normal I/O operations, except that
  224.     the reported error address is meaningless.}
  225.  
  226. procedure lsIoff;
  227.   {-Has the same effect with respect to lsReadLn, lsWriteLn as the $I-
  228.     compiler has with respect to normal I/O operations, except that
  229.     the reported error address is meaningless.}
  230.  
  231. function lsIoResult : word;
  232.   {-Returns the value of IoResult resulting from the last lsReadLn or
  233.     lsWriteLn. NOTE: You MUST use lsIoResult for checking lsReadLn,
  234.     lsWriteLn. If you call IoResult instead, you will always get a 0
  235.     return.}
  236.  
  237.   {==========================================================================}
  238.               IMPLEMENTATION
  239.   {==========================================================================}
  240.  
  241.  
  242. const
  243.   RuntimeErrorNumber  : word = 250;
  244.   lsIoRes : word = 0;
  245.   lsIoCheck : boolean = true;
  246.   Blank : char = #32;
  247.   MaxRingSize   = 100;
  248.   RingSizeM1 = MaxRingSize - 1;
  249.  
  250. var
  251.   Ring       : array[0..RingSizeM1] of LongString;
  252.   RingPtr    : ShortInt;
  253.  
  254. function Ptr2Str(P:pointer) : string; {For debugging only!}
  255.   begin
  256.     Ptr2Str := HexPtr(Normalized(P));
  257.     end;
  258.  
  259. function max(X, Y : word) : word;
  260.   begin
  261.     if X >= Y then
  262.       max := X
  263.     else
  264.       max := Y;
  265.     end; {max}
  266.  
  267. function min(X, Y : word) : word;
  268.   begin
  269.     if X <= Y then
  270.       min := X
  271.     else
  272.       min := Y;
  273.     end; {min}
  274.  
  275. function lsInit(var A  : LongString; L : word)  : boolean;
  276.   {"Declares" a LongString of maximum declared length L and establishes
  277.    space for it on the heap. Returns false if L is greater than
  278.    MaxLongString.}
  279.   var
  280.     B1  : boolean;
  281.   begin
  282.     if L > MaxLongString then begin
  283.       lsInit := false;
  284.       exit;
  285.       end {if}
  286.     else begin
  287.       B1 := GetMemCheck(A, L+(2*SizeOf(word)));
  288.       if not B1 then RunError(RuntimeErrorNumber);
  289.       lsInit := true;
  290.       A^.dLength := L;
  291.       A^.Length := 0;
  292.       end; {else}
  293.     end; {lsInit}
  294.  
  295. procedure lsDispose(var A : LongString);
  296.   {-Dispose of A, releasing its heap space}
  297.   begin
  298.     FreeMemCheck(A, A^.dLength+(2*SizeOf(word)));
  299.     A := nil;
  300.     end; {lsDispose}
  301.  
  302. function NextInRing(L  : word) : LongString;
  303.   {-lsInits the next LongString on the ring buffer, lsDisposing of its
  304.     current contents, if any.}
  305.   var
  306.     RuntimeErrorNumSave : word;
  307.   begin
  308.     RuntimeErrorNumber := 251;
  309.     RingPtr := (RingPtr+1) mod RingSize;
  310.     if Ring[RingPtr] <> nil then
  311.       lsDispose(Ring[RingPtr]);
  312.     if not lsInit(Ring[RingPtr], L) then
  313.       NextInRing := nil
  314.     else
  315.       NextInRing := Ring[RingPtr];
  316.     RuntimeErrorNumber := RuntimeErrorNumSave;
  317.     end; {NextInRing}
  318.  
  319. procedure lsTransfer(A, B : LongString);
  320.   {Transfers the contents of A to B.
  321.    Truncates if the declared length of B is less than the length of A.}
  322.   begin
  323.     if Normalized(A) = Normalized(B) then exit;
  324.     B^.Length := min(A^.Length, B^.dLength);
  325.     move(A^.lsData, B^.lsData, B^.Length);
  326.     end; {lsTransfer}
  327.  
  328. function lsLength(A : LongString) : word;
  329.   {-Return the length of a LongString string}
  330.   begin
  331.     lsLength := A^.Length;
  332.     end; {lsLength}
  333.  
  334. function lsSizeOf(A : LongString) : word;
  335.   {-Returns the **declared** length of A + the overhead words}
  336.   begin
  337.     lsSizeOf := A^.dLength + (2*SizeOf(word));
  338.     end; {lsSizeOf}
  339.  
  340. function lsLongString2Str(A : LongString) : string;
  341.   {-Convert LongString to Turbo string, truncating if longer than 255 chars}
  342.   var
  343.     S : string;
  344.   begin
  345.     S[0] := char(min(A^.Length, 255));
  346.     move(A^.lsData, S[1], byte(S[0]));
  347.     lsLongString2Str := S;
  348.     end; {lsLongString2Str}
  349.  
  350. procedure lsStr2LongString(S : string; A : LongString);
  351.   {-Convert a Turbo string into a LongString. The LongString must have
  352.    been declared.}
  353.   begin
  354.     if A = nil then exit;
  355.     A^.Length := min(A^.dLength, byte(S[0]));
  356.     move(S[1], A^.lsData, A^.Length);
  357.     end; {lsStr2LongString}
  358.  
  359. function lsStr2LongStringF(S : string)  : LongString;
  360.   {-Convert a Turbo string into a LongString}
  361.   var
  362.     ThisLs  : LongString;
  363.   begin
  364.     ThisLs := NextInRing(byte(S[0]));
  365.     lsStr2LongStringF := ThisLs;
  366.     lsStr2LongString(S, ThisLs);
  367.     end; {lsStr2LongStringF}
  368.  
  369. procedure lsCopy(A  : LongString; Start, Len  : word; B : LongString);
  370.   {-Return a long substring of A. Note Start=1 for first char in A}
  371.   begin
  372.     if B = nil then exit;
  373.     if (A = nil) or (Start > A^.Length) then begin
  374.       B^.Length := 0;
  375.       exit;
  376.       end;
  377.     if ((Start-1) + Len) > A^.Length then
  378.       Len := A^.Length - Start + 1;
  379.     B^.Length := min(Len, B^.dLength);
  380.     move(A^.lsData[Start], B^.lsData, Len);
  381.     end; {lsCopy}
  382.  
  383. function lsCopyF(A  : LongString; Start, Len  : word)  : LongString;
  384.   {-Return a long substring of A. Note Start=1 for first char in A}
  385.   var
  386.     ThisLs  : LongString;
  387.   begin
  388.     ThisLs := NextInRing(Len);
  389.     lsCopyF := ThisLs;
  390.     lsCopy(A, Start, Len, ThisLs);
  391.     end; {lsCopyF}
  392.  
  393. procedure lsDelete(A : LongString; Start, Len : word; B : LongString);
  394.   {-Delete Len characters of A, starting at position Start}
  395.   begin
  396.     lsTransfer(A, B);
  397.     if Start > B^.Length then exit;
  398.     if Len > B^.Length - (Start - 1) then
  399.       Len := B^.Length - (Start - 1);
  400.     B^.Length := B^.Length - Len;
  401.     move(B^.lsData[Start+Len], B^.lsData[Start], B^.Length - (Start - 1));
  402.     end; {lsDelete}
  403.  
  404. function lsDeleteF(A  : LongString; Start, Len  : word) : LongString;
  405.   {-Delete Len characters of A, starting at position Start}
  406.   {-The function form returns A unchanged.}
  407.   var
  408.     ThisLs  : LongString;
  409.   begin
  410.     if Start > A^.Length then begin
  411.       lsDeleteF := nil;
  412.       exit;
  413.       end;
  414.     if Len > A^.Length - (Start - 1) then
  415.       Len := A^.Length - (Start - 1);
  416.     ThisLs := NextInRing(A^.Length - Len);
  417.     ThisLs^.Length := A^.Length - Len;
  418.     move(A^.lsData[1], ThisLs^.lsData[1], Start - 1);
  419.     move(A^.lsData[Start+Len], ThisLs^.lsData[Start], A^.Length - (Start - 1));
  420.     lsDeleteF := ThisLs;
  421.     end; {lsDeleteF}
  422.  
  423. procedure lsConcat(A, B, C : LongString);
  424.   {-Concatenate two LongString strings, returning a third}
  425.   var
  426.     CpyFromA,
  427.     CpyFromB  : word;
  428.   begin
  429.     if A^.Length > C^.dLength then begin
  430.       CpyFromA := C^.dLength;
  431.       CpyFromB := 0;
  432.       end
  433.     else begin
  434.       if A^.Length + B^.Length > C^.dLength then begin
  435.         CpyFromA := A^.Length;
  436.         CpyFromB := C^.dLength - CpyFromA;
  437.         end
  438.       else begin
  439.         CpyFromA := A^.Length;
  440.         CpyFromB := B^.Length;
  441.         end;
  442.       end;
  443.     C^.Length := CpyFromA + CpyFromB;
  444.     move(A^.lsData, C^.lsData, CpyFromA);
  445.     move(B^.lsData, C^.lsData[CpyFromA + 1], CpyFromB);
  446.     end; {lsConcat}
  447.  
  448. function lsConcatF(A, B : LongString) : LongString;
  449.   {-Concatenate two LongString strings, returning a third}
  450.   var
  451.     ThisLs  : LongString;
  452.     CpyFromB: word;
  453.   begin
  454.     if A^.Length + B^.Length > MaxLongString then
  455.       CpyFromB := MaxLongString - A^.Length
  456.     else
  457.       CpyFromB := B^.Length;
  458.     ThisLs := NextInRing(A^.Length + CpyFromB);
  459.     lsConcatF := ThisLs;
  460.     lsConcat(A, B, ThisLs);
  461.     end; {lsConcatF}
  462.  
  463. procedure lsConcatStr2Ls(A : LongString; S : string; C : LongString);
  464.   {-Concatenate a string to a LongString, returning a new LongString}
  465.   var
  466.     LS  : LongString;
  467.   begin
  468.     if not lsInit(LS, A^.Length + byte(S[0])) then exit;
  469.     lsStr2LongString(S, LS);
  470.     lsConcat(A, LS, C);
  471.     lsDispose(LS);
  472.     end; {lsConcatStr2Ls}
  473.  
  474. function lsConcatStr2LsF(A : LongString; S : string)  : LongString;
  475.   {-Concatenate a string to a LongString, returning a new LongString}
  476.   var
  477.     LS  : LongString;
  478.   begin
  479.     if not lsInit(LS, A^.Length + byte(S[0])) then exit;
  480.     lsStr2LongString(S, LS);
  481.     lsConcatStr2LsF := lsConcatF(A, LS);
  482.     lsDispose(LS);
  483.     end; {lsConcatStr2LsF}
  484.  
  485. procedure lsConcatLs2Str(S : string; A : LongString; C : LongString);
  486.   {-Concatenate a LongString to a string, returning a new LongString}
  487.   var
  488.     LS  : LongString;
  489.   begin
  490.     if not lsInit(LS, A^.Length + byte(S[0])) then exit;
  491.     lsStr2LongString(S, LS);
  492.     lsConcat(LS, A, C);
  493.     lsDispose(LS);
  494.     end; {lsConcatLs2Str}
  495.  
  496. function lsConcatLs2StrF(S : string; A : LongString)  : LongString;
  497.   {-Concatenate a LongString to a string, returning a new LongString}
  498.   var
  499.     LS  : LongString;
  500.   begin
  501.     if not lsInit(LS, A^.Length + byte(S[0])) then exit;
  502.     lsStr2LongString(S, LS);
  503.     lsConcatLs2StrF := lsConcatF(LS, A);
  504.     lsDispose(LS);
  505.     end; {lsConcatLs2StrF}
  506.  
  507. procedure lsInsert(A, Obj : LongString; Start : word; B : LongString);
  508.   {-Insert LongString Obj into A at position Start returning a new LongString}
  509.   var
  510.     FrontOfA,
  511.     RestOfA,
  512.     CpyFromO  : word;
  513.   begin
  514.     FrontOfA := min(Start-1, B^.dLength);
  515.     if (B^.dLength - FrontOfA) > Obj^.Length then
  516.       CpyFromO := Obj^.Length
  517.     else
  518.       CpyFromO := B^.dLength - FrontOfA;
  519.     if (B^.dLength - (FrontOfA + CpyFromO)) > (A^.Length - FrontOfA) then
  520.       RestOfA := A^.Length - FrontOfA
  521.     else
  522.       RestOfA := B^.dLength - (FrontOfA + CpyFromO);
  523.     B^.Length := FrontOfA + CpyFromO + RestOfA;
  524.     move(A^.lsData, B^.lsData, FrontOfA);
  525.     move(A^.lsData[Start], B^.lsData[FrontOfA + CpyFromO + 1], RestOfA);
  526.     move(Obj^.lsData, B^.lsData[Start], CpyFromO);
  527.     end; {lsInsert}
  528.  
  529. function lsInsertF(A, Obj : LongString; Start : word) : LongString;
  530.   {-Insert LongString Obj into A at position Start returning a new LongString}
  531.   var
  532.     ThisLs  : LongString;
  533.   begin
  534.     ThisLs := NextInRing(A^.Length + Obj^.Length);
  535.     lsInsertF := ThisLs;
  536.     lsInsert(A, Obj, Start, ThisLs);
  537.     end; {lsInsertF}
  538.  
  539. procedure lsInsertStr(A : LongString; Obj : string;
  540.                       Start : word; B : LongString);
  541.   {-Insert string Obj into A at position Start returning a new LongString}
  542.   var
  543.     LS  : LongString;
  544.   begin
  545.     if not lsInit(LS, byte(Obj[0])) then exit;
  546.     lsStr2LongString(Obj, LS);
  547.     lsInsert(A, LS, Start, B);
  548.     lsDispose(LS);
  549.     end; {lsInsertStr}
  550.  
  551. function lsInsertStrF(A : LongString; Obj : string;
  552.                       Start : word) : LongString;
  553.   {-Insert string Obj into A at position Start returning a new LongString}
  554.   var
  555.     LS  : LongString;
  556.   begin
  557.     if not lsInit(LS, byte(Obj[0])) then exit;
  558.     lsStr2LongString(Obj, LS);
  559.     lsInsertStrF := lsInsertF(A, LS, Start);
  560.     lsDispose(LS);
  561.     end; {lsInsertStrF}
  562.  
  563. procedure lsUpcase(A, B : LongString);
  564.   {-Uppercase the LongString in A, returning B}
  565.   var
  566.     W1    : word;
  567.   begin
  568.     lsTransfer(A, B);
  569.     for W1 := 1 to B^.Length do
  570.       B^.lsData[W1] := Upcase(B^.lsData[W1]);
  571.     end; {lsUpcase}
  572.  
  573. function lsUpcaseF(A  : LongString) : LongString;
  574.   {-Uppercase the LongString in A, returning B}
  575.   var
  576.     ThisLs  : LongString;
  577.   begin
  578.     ThisLs := NextInRing(A^.Length);
  579.     lsUpcase(A, ThisLs);
  580.     lsUpcaseF := ThisLs;
  581.     end; {lsUpcaseF}
  582.  
  583. procedure lsLocase(A, B : LongString);
  584.   {-Lowercase the LongString in A, returning B}
  585.   var
  586.     W1    : word;
  587.   begin
  588.     lsTransfer(A, B);
  589.     for W1 := 1 to B^.Length do
  590.       B^.lsData[W1] := Locase(B^.lsData[W1]);
  591.     end; {lsLocase}
  592.  
  593. function lsLocaseF(A  : LongString) : LongString;
  594.   {-Lowercase the LongString in A, returning B}
  595.   var
  596.     ThisLs  : LongString;
  597.   begin
  598.     ThisLs := NextInRing(A^.Length);
  599.     lsLocase(A, ThisLs);
  600.     lsLocaseF := ThisLs;
  601.     end; {lsLocaseF}
  602.  
  603. function lsComp(A1, A2 : LongString) : lsCompType;
  604.   {-Compares A1 to A2, returning LESS, EQUAL, or GREATER}
  605.   var
  606.     W1,
  607.     Search  : word;
  608.     LgthA1A2: lsCompType;
  609.   begin
  610.     if A1^.Length = A2^.Length then
  611.       LgthA1A2 := Equal
  612.     else
  613.       if A1^.Length < A2^.Length then
  614.         LgthA1A2 := Less
  615.       else
  616.         LgthA1A2 := Greater;
  617.     Search := min(A1^.Length, A2^.Length);
  618.     W1 := 1;
  619.     while (W1 < Search) and (A1^.lsData[W1] = A2^.lsData[W1]) do
  620.       inc(W1);
  621.     if A1^.lsData[W1] = A2^.lsData[W1] then begin
  622.       lsComp := LgthA1A2;
  623.       exit;
  624.       end;
  625.     if A1^.lsData[W1] < A2^.lsData[W1] then begin
  626.       lsComp := Less;
  627.       exit;
  628.       end;
  629.     if A1^.lsData[W1] > A2^.lsData[W1] then begin
  630.       lsComp := Greater;
  631.       end;
  632.     end; {lsComp}
  633.  
  634. function lsPosStr(Obj : string; A : LongString) : word;
  635.   {-Return the position of the string Obj in A, returning NotFound if
  636.    not found}
  637.   begin
  638.     lsPosStr := succ(Search(A^.lsData, A^.Length, Obj[1], byte(Obj[0])));
  639.     end; {lsPosStr}
  640.  
  641. function lsPos(Obj, A : LongString) : word;
  642.   {-Return the position of Obj in A, returning NotFound if not found}
  643.   begin
  644.     lsPos := succ(Search(A^.lsData, A^.Length, Obj^.lsData, Obj^.Length));
  645.     end; {lsPos}
  646.  
  647. function lsPosStrUC(Obj : string; A : LongString) : word;
  648.   {-Return the position of the string Obj in A, returning NotFound if
  649.    not found. The search is not case sensitive.}
  650.   begin
  651.     lsPosStrUC := succ(SearchUC(A^.lsData, A^.Length, Obj[1], byte(Obj[0])));
  652.     end; {lsPosStrUC}
  653.  
  654. function lsPosUC(Obj, A : LongString) : word;
  655.   {-Return the position of Obj in A, returning NotFound if not found.
  656.    The search is not case sensitive.}
  657.   begin
  658.     lsPosUC := succ(SearchUC(A^.lsData, A^.Length, Obj^.lsData, Obj^.Length));
  659.     end; {lsPosUC}
  660.  
  661. function CountPrim(A, Obj : LongString;
  662.                    CaseSens  {true if case sensitive} : boolean)  : word;
  663.   var
  664.     Next,
  665.     Now,
  666.     Count : word;
  667.   begin
  668.     Next := 1;
  669.     Now := 1;
  670.     Count := 0;
  671.     repeat
  672.       if CaseSens then
  673.         Now := succ(Search(A^.lsData[Next], A^.Length-Next+1,
  674.                            Obj^.lsData, Obj^.Length))
  675.       else
  676.         Now := succ(SearchUC(A^.lsData[Next], A^.Length-Next+1,
  677.                            Obj^.lsData, Obj^.Length));
  678.       if Now <> 0 then begin
  679.         Next := Next + Now + Obj^.Length - 1;
  680.         inc(Count);
  681.         end;
  682.       until Now = 0;
  683.     CountPrim := Count;
  684.     end; {CountPrim}
  685.  
  686.   {-Returns the number of occurrences of Obj in A}
  687. function lsCount(A, Obj : LongString):  word;
  688.   begin
  689.     lsCount := CountPrim(A, Obj, true);
  690.     end; {lsCount}
  691. function lsCountStr(A : LongString; Obj : string) : word;
  692.   var
  693.     LS  : LongString;
  694.   begin
  695.     if not lsInit(LS, byte(Obj[0])) then exit;
  696.     lsStr2LongString(Obj, LS);
  697.     lsCountStr := lsCount(A, LS);
  698.     lsDispose(LS);
  699.     end; {lsCountStr}
  700.  
  701.   {-Returns the number of occurrences of Obj in A}
  702.   { The search is not CASE SENSITIVE.}
  703. function lsCountUC(A, Obj : LongString):  word;
  704.   begin
  705.     lsCountUC := CountPrim(A, Obj, false);
  706.     end; {lsCountUC}
  707. function lsCountStrUC(A : LongString; Obj : string) : word;
  708.   var
  709.     LS  : LongString;
  710.   begin
  711.     if not lsInit(LS, byte(Obj[0])) then exit;
  712.     lsStr2LongString(Obj, LS);
  713.     lsCountStrUC := lsCountUC(A, LS);
  714.     lsDispose(LS);
  715.     end; {lsCountStrUC}
  716.  
  717. procedure RepDelPrim(In0, Obj, Obj1, Out : LongString;
  718.                      RepOrDel, {true if to replace}
  719.                      CaseSens  {true if case sensitive} : boolean);
  720.   var
  721.     In1,
  722.     Scr   : LongString;
  723.     W1    : word;
  724.   function GetPos : word;
  725.     begin
  726.       if CaseSens then
  727.         GetPos := lsPos(Obj, In1)
  728.       else
  729.         GetPos := lsPosUC(Obj, In1);
  730.       end; {GetPos}
  731.   begin
  732.     if not lsInit(In1, In0^.Length) then exit;
  733.     lsTransfer(In0, In1);
  734.     W1 := GetPos;
  735.     if W1 = NotFound then begin
  736.       lsTransfer(In1, Out);
  737.       lsDispose(In1);
  738.       exit;
  739.       end;
  740.     if not lsInit(Scr, In1^.Length) then exit;
  741.     Out^.Length := 0;
  742.     while W1 <> NotFound do begin
  743.       lsCopy(In1, 1, W1-1, Scr);
  744.       lsConcat(Out, Scr, Out);
  745.       if RepOrDel then
  746.         lsConcat(Out, Obj1, Out);
  747.       lsDelete(In1, 1, W1 + Obj^.Length - 1, In1);
  748.       W1 := GetPos;
  749.       end; {while}
  750.     lsConcat(Out, In1, Out);
  751.     lsDispose(In1);
  752.     lsDispose(Scr);
  753.     end; {RepDelPrim}
  754.  
  755.   {-Deletes all occurrences of Obj in A}
  756. procedure lsDelAll(A, Obj, B : LongString);
  757.   begin
  758.     RepDelPrim(A, Obj, nil, B, false, true);
  759.     end; {lsDelAll}
  760. function lsDelAllF(A, Obj : LongString):  LongString;
  761.   var
  762.     LS  : LongString;
  763.   begin
  764.     LS := NextInRing(A^.Length - (lsCount(A, Obj) * Obj^.Length));
  765.     lsDelAll(A, Obj, LS);
  766.     lsDelAllF := LS;
  767.     end; {lsDelAllF}
  768. procedure lsDelAllStr(A : LongString; Obj : string; B : LongString);
  769.   var
  770.     LS  : LongString;
  771.   begin
  772.     if not lsInit(LS, A^.Length - (lsCountStr(A, Obj) * byte(Obj[0]))) then
  773.       exit;
  774.     lsStr2LongString(Obj, LS);
  775.     lsDelAll(A, LS, B);
  776.     lsDispose(LS);
  777.     end; {lsDelAllStr}
  778. function lsDelAllStrF(A : LongString; Obj : string) : LongString;
  779.   var
  780.     LS  : LongString;
  781.   begin
  782.     if not lsInit(LS, A^.Length - (lsCountStr(A, Obj) * byte(Obj[0]))) then
  783.       exit;
  784.     lsStr2LongString(Obj, LS);
  785.     lsDelAllStrF := lsDelAllF(A, LS);
  786.     lsDispose(LS);
  787.     end; {lsDelAllStrF}
  788.  
  789.   {-Deletes all occurrences of Obj in A}
  790.   { The search is not CASE SENSITIVE.}
  791. procedure lsDelAllUC(A, Obj, B : LongString);
  792.   begin
  793.     RepDelPrim(A, Obj, nil, B, false, false);
  794.     end; {lsDelAllUC}
  795. function lsDelAllUCF(A, Obj : LongString):  LongString;
  796.   var
  797.     LS  : LongString;
  798.   begin
  799.     LS := NextInRing(A^.Length - (lsCount(A, Obj) * Obj^.Length));
  800.     lsDelAllUC(A, Obj, LS);
  801.     lsDelAllUCF := LS;
  802.     end; {lsDelAllUCF}
  803. procedure lsDelAllStrUC(A : LongString; Obj : string; B : LongString);
  804.   var
  805.     LS  : LongString;
  806.   begin
  807.     if not lsInit(LS, A^.Length - (lsCountStrUC(A, Obj) * byte(Obj[0]))) then
  808.       exit;
  809.     lsStr2LongString(Obj, LS);
  810.     lsDelAllUC(A, LS, B);
  811.     lsDispose(LS);
  812.     end; {lsDelAllStrUC}
  813. function lsDelAllStrUCF(A : LongString; Obj : string) : LongString;
  814.   var
  815.     LS  : LongString;
  816.   begin
  817.     if not lsInit(LS, A^.Length - (lsCountStr(A, Obj) * byte(Obj[0]))) then
  818.       exit;
  819.     lsStr2LongString(Obj, LS);
  820.     lsDelAllStrUCF := lsDelAllUCF(A, LS);
  821.     lsDispose(LS);
  822.     end; {lsDelAllStrUCF}
  823.  
  824.   {-Replaces all occurrences of Obj in A with Obj1}
  825. procedure lsRepAll(A, Obj, Obj1, B : LongString);
  826.   begin
  827.     RepDelPrim(A, Obj, Obj1, B, true, true);
  828.     end; {lsRepAll}
  829. function lsRepAllF(A, Obj, Obj1 : LongString):  LongString;
  830.   var
  831.     LS    : LongString;
  832.   begin
  833.     LS := NextInRing(A^.Length +
  834.                     (lsCount(A, Obj) * (Obj1^.Length - Obj^.Length)));
  835.     lsRepAll(A, Obj, Obj1, LS);
  836.     lsRepAllF := LS;
  837.     end; {lsRepAllF}
  838. procedure lsRepAllStr(A : LongString; Obj, Obj1 : string; B : LongString);
  839.   var
  840.     LS0,
  841.     LS1  : LongString;
  842.   begin
  843.     if not lsInit(LS0, byte(Obj[0])) then exit;
  844.     lsStr2LongString(Obj, LS0);
  845.     if not lsInit(LS1, byte(Obj1[0])) then exit;
  846.     lsStr2LongString(Obj1, LS1);
  847.     lsRepAll(A, LS0, LS1, B);
  848.     lsDispose(LS0);
  849.     lsDispose(LS1);
  850.     end; {lsRepAllStr}
  851. function lsRepAllStrF(A : LongString; Obj, Obj1 : string) : LongString;
  852.   var
  853.     LS0,
  854.     LS1   : LongString;
  855.   begin
  856.     if not lsInit(LS0, byte(Obj[0])) then exit;
  857.     lsStr2LongString(Obj, LS0);
  858.     if not lsInit(LS1, byte(Obj1[0])) then exit;
  859.     lsStr2LongString(Obj1, LS1);
  860.     lsRepAllStrF := lsRepAllF(A, LS0, LS1);
  861.     lsDispose(LS0);
  862.     lsDispose(LS1);
  863.     end; {lsRepAllStrF}
  864.  
  865.   {-Replaces all occurrences of Obj in A with Obj1}
  866.   { The search is not CASE SENSITIVE.}
  867. procedure lsRepAllUC(A, Obj, Obj1, B : LongString);
  868.   begin
  869.     RepDelPrim(A, Obj, Obj1, B, true, false);
  870.     end; {lsRepAllUC}
  871. function lsRepAllUCF(A, Obj, Obj1 : LongString):  LongString;
  872.   var
  873.     LS    : LongString;
  874.   begin
  875.     LS := NextInRing(A^.Length +
  876.                     (lsCountUC(A, Obj) * (Obj1^.Length - Obj^.Length)));
  877.     lsRepAllUC(A, Obj, Obj1, LS);
  878.     lsRepAllUCF := LS;
  879.     end; {lsRepAllUCF}
  880. procedure lsRepAllStrUC(A : LongString; Obj, Obj1 : string; B : LongString);
  881.   var
  882.     LS0,
  883.     LS1  : LongString;
  884.   begin
  885.     if not lsInit(LS0, byte(Obj[0])) then exit;
  886.     lsStr2LongString(Obj, LS0);
  887.     if not lsInit(LS1, byte(Obj1[0])) then exit;
  888.     lsStr2LongString(Obj1, LS1);
  889.     lsRepAllUC(A, LS0, LS1, B);
  890.     lsDispose(LS0);
  891.     lsDispose(LS1);
  892.     end; {lsRepAllStrUC}
  893. function lsRepAllStrUCF(A : LongString; Obj, Obj1 : string) : LongString;
  894.   var
  895.     LS0,
  896.     LS1   : LongString;
  897.   begin
  898.     if not lsInit(LS0, byte(Obj[0])) then exit;
  899.     lsStr2LongString(Obj, LS0);
  900.     if not lsInit(LS1, byte(Obj1[0])) then exit;
  901.     lsStr2LongString(Obj1, LS1);
  902.     lsRepAllStrUCF := lsRepAllUCF(A, LS0, LS1);
  903.     lsDispose(LS0);
  904.     lsDispose(LS1);
  905.     end; {lsRepAllStrUCF}
  906.  
  907. procedure lsGetNextPrim(LS1, LS2  : LongString; Delims  : DelimSetType);
  908.   var
  909.     W1  : word;
  910.   begin
  911.     if lsLength(LS1) = 0 then begin
  912.       LS2^.Length := 0;
  913.       exit;
  914.       end;
  915.     W1 := 1;
  916.     while (LS1^.lsData[W1] in Delims) and (W1 <= lsLength(LS1)) do
  917.       inc(W1);
  918.     dec(W1);
  919.     lsDelete(LS1, 1, W1, LS1);
  920.     if lsLength(LS1) = 0 then
  921.       LS2^.Length := 0
  922.     else begin
  923.       W1 := 1;
  924.       while (not (LS1^.lsData[W1] in Delims)) and (W1 <= lsLength(LS1)) do
  925.         inc(W1);
  926.       dec(W1);
  927.       if W1 <> 0 then begin
  928.         lsCopy(LS1, 1, W1, LS2);
  929.         lsDelete(LS1, 1, W1, LS1);
  930.         end
  931.       else begin
  932.         lsTransfer(LS1, LS2);
  933.         LS1^.Length := 0;
  934.         end;
  935.       end;
  936.     end; {lsGetNextPrim}
  937.  
  938. procedure lsGetNext(LS1, LS2  : LongString);
  939.   begin
  940.     lsGetNextPrim(LS1, LS2, DelimSet);
  941.     end;
  942.  
  943. function lsGetNextF(LS1 : LongString) : LongString;
  944.   var
  945.     Scr,
  946.     ThisLs  : LongString;
  947.   begin
  948.     if not lsInit(Scr, LS1^.Length) then exit;
  949.     lsGetNextPrim(LS1, Scr, DelimSet);
  950.     ThisLs := NextInRing(Scr^.Length);
  951.     lsTransfer(Scr, ThisLs);
  952.     lsDispose(Scr);
  953.     lsGetNextF := ThisLs;
  954.     end; {lsGetNextF}
  955.  
  956. procedure lsGetNextStr(LS1  : LongString; var S2  : string);
  957.   var
  958.     LS2     : LongString;
  959.   begin
  960.     if not lsInit(LS2, LS1^.Length) then exit;
  961.     lsGetNextPrim(LS1, LS2, DelimSet);
  962.     S2 := lsLongString2Str(LS2);
  963.     lsDispose(LS2);
  964.     end; {lsGetNextStr}
  965.  
  966. function lsGetNextStrF(LS1  : LongString) : string;
  967.   var
  968.     LS2     : LongString;
  969.   begin
  970.     if not lsInit(LS2, LS1^.Length) then exit;
  971.     lsGetNextPrim(LS1, LS2, DelimSet);
  972.     lsGetNextStrF := lsLongString2Str(LS2);
  973.     lsDispose(LS2);
  974.     end; {lsGetNextStrF}
  975.  
  976. procedure lsCharStr(Ch : Char; Len : word; A : LongString);
  977.   {-Return a LongString of length Len filled with Ch}
  978.   begin
  979.     A^.Length := min(Len, A^.dLength);
  980.     FillChar(A^.lsData, A^.Length, Ch);
  981.     end; {lsCharStr}
  982.  
  983. function lsCharStrF(Ch : Char; Len : word) : LongString;
  984.   {-Return a LongString of length Len filled with Ch}
  985.   var
  986.     ThisLs  : LongString;
  987.   begin
  988.     ThisLs := NextInRing(Len);
  989.     lsCharStr(Ch, Len, ThisLs);
  990.     lsCharStrF := ThisLs;
  991.     end; {lsCharStrF}
  992.  
  993. procedure lsPadCh(A : LongString; Ch : Char; Len : word; B : LongString);
  994.   {-Right-pad the LongString in A to length Len with Ch, returning B}
  995.   var
  996.     CpyFromA,
  997.     LenOfCh   : word;
  998.   begin
  999.     Len := min(B^.dLength, Len);
  1000.     CpyFromA := min(A^.Length, Len);
  1001.     if Len > CpyFromA then
  1002.       LenOfCh := Len - CpyFromA
  1003.     else
  1004.       LenOfCh := 0;
  1005.     B^.Length := Len;
  1006.     move(A^.lsData, B^.lsData, CpyFromA);
  1007.     FillChar(B^.lsData[CpyFromA+1], LenOfCh, Ch);
  1008.     end; {lsPadCh}
  1009.  
  1010. function lsPadChF(A : LongString; Ch : Char; Len : word)  : LongString;
  1011.   {-Right-pad the LongString in A to length Len with Ch, returning B}
  1012.   var
  1013.     ThisLs  : LongString;
  1014.   begin
  1015.     ThisLs := NextInRing(Len);
  1016.     lsPadCh(A, Ch, Len, ThisLs);
  1017.     lsPadChF := ThisLs;
  1018.     end; {lsPadChF}
  1019.  
  1020. procedure lsPad(A : LongString; Len : word; B : LongString);
  1021.   {-Right-pad the LongString in A to length Len with blanks, returning B}
  1022.   begin
  1023.     lsPadCh(A, Blank, Len, B);
  1024.     end; {lsPad}
  1025.  
  1026. function lsPadF(A : LongString; Len : word) : LongString;
  1027.   {-Right-pad the LongString in A to length Len with blanks, returning B}
  1028.   begin
  1029.     lsPadF := lsPadChF(A, Blank, Len);
  1030.     end; {lsPad}
  1031.  
  1032. procedure lsLeftPadCh(A : LongString; Ch : Char; Len : word; B : LongString);
  1033.   {-Left-pad the LongString in A to length Len with Ch, returning B}
  1034.   var
  1035.     CpyFromA,
  1036.     LenOfCh   : word;
  1037.     ThisLs    : LongString;
  1038.   begin
  1039.     Len := min(B^.dLength, Len);
  1040.     ThisLs := NextInRing(Len);
  1041.     CpyFromA := min(A^.Length, Len);
  1042.     if Len > CpyFromA then
  1043.       LenOfCh := Len - CpyFromA
  1044.     else
  1045.       LenOfCh := 0;
  1046.     ThisLs^.Length := Len;
  1047.     move(A^.lsData, ThisLs^.lsData[LenOfCh+1], CpyFromA);
  1048.     FillChar(ThisLs^.lsData, LenOfCh, Ch);
  1049.     lsTransfer(ThisLs, B);
  1050.     end; {lsLeftPadCh}
  1051.  
  1052. function lsLeftPadChF(A : LongString; Ch : Char; Len : word)  : LongString;
  1053.   {-Left-pad the LongString in A to length Len with Ch, returning B}
  1054.   var
  1055.     ThisLs  : LongString;
  1056.   begin
  1057.     ThisLs := NextInRing(Len);
  1058.     lsLeftPadCh(A, Ch, Len, ThisLs);
  1059.     lsLeftPadChF := ThisLs;
  1060.     end; {lsLeftPadChF}
  1061.  
  1062. procedure lsLeftPad(A : LongString; Len : word; B : LongString);
  1063.   {-Left-pad the LongString in A to length Len with blanks, returning B}
  1064.   begin
  1065.     lsLeftPadCh(A, Blank, Len, B);
  1066.     end; {lsLeftPad}
  1067.  
  1068. function lsLeftPadF(A : LongString; Len : word) : LongString;
  1069.   {-Left-pad the LongString in A to length Len with blanks, returning B}
  1070.   begin
  1071.     lsLeftPadF := lsLeftPadChF(A, Blank, Len);
  1072.     end; {lsLeftPad}
  1073.  
  1074. procedure lsTrimLead(A, B : LongString);
  1075.   {-Return a LongString with leading white space removed}
  1076.   var
  1077.     W1    : word;
  1078.   begin
  1079.     lsTransfer(A, B);
  1080.     W1 := 1;
  1081.     while (W1 <= B^.Length) and (B^.lsData[W1] <= Blank) do
  1082.       inc(W1);
  1083.     if W1 <= B^.Length then begin
  1084.       move(B^.lsData[W1], B^.lsData[1], B^.Length - W1 + 1);
  1085.       B^.Length := B^.Length - W1 + 1;
  1086.       end;
  1087.     end; {lsTrimLead}
  1088.  
  1089. function lsTrimLeadF(A  : LongString): LongString;
  1090.   {-Return a LongString with leading white space removed}
  1091.   var
  1092.     ThisLs  : LongString;
  1093.   begin
  1094.     ThisLs := NextInRing(A^.Length);
  1095.     lsTrimLead(A, ThisLs);
  1096.     lsTrimLeadF := ThisLs;
  1097.     end; {lsTrimLeadF}
  1098.  
  1099. procedure lsTrimTrail(A, B : LongString);
  1100.   {-Return a LongString with trailing white space removed}
  1101.   var
  1102.     W1    : word;
  1103.   begin
  1104.     lsTransfer(A, B);
  1105.     W1 := B^.Length;
  1106.     while (W1 >= 1) and (B^.lsData[W1] <= Blank) do begin
  1107.       dec(W1);
  1108.       dec(B^.Length);
  1109.       end;
  1110.     end; {lsTrimTrail}
  1111.  
  1112. function lsTrimTrailF(A : LongString) : LongString;
  1113.   {-Return a LongString with trailing white space removed}
  1114.   var
  1115.     ThisLs  : LongString;
  1116.   begin
  1117.     ThisLs := NextInRing(A^.Length);
  1118.     lsTrimTrail(A, ThisLs);
  1119.     lsTrimTrailF := ThisLs;
  1120.     end; {lsTrimTrailF}
  1121.  
  1122. procedure lsTrim(A, B : LongString);
  1123.   {-Return a LongString with leading and trailing white space removed}
  1124.   var
  1125.     ThisLs  : LongString;
  1126.   begin
  1127.     if not lsInit(ThisLs, A^.Length) then exit;
  1128.     lsTransfer(A, ThisLs);
  1129.     lsTrimLead(lsTrimTrailF(ThisLs), B);
  1130.     lsDispose(ThisLs);
  1131.     end; {lsTrim}
  1132.  
  1133. function lsTrimF(A  : LongString) : LongString;
  1134.   {-Return a LongString with leading and trailing white space removed}
  1135.   var
  1136.     ThisLs  : LongString;
  1137.   begin
  1138.     ThisLs := NextInRing(A^.Length);
  1139.     lsTrim(A, ThisLs);
  1140.     lsTrimF := ThisLs;
  1141.     end; {lsTrimF}
  1142.  
  1143. procedure lsCenterCh(A : LongString; Ch : Char; Width : word; B : LongString);
  1144.   {-Return a LongString centered in a LongString of Ch with specified Width}
  1145.   var
  1146.     W1      : word;
  1147.   begin
  1148.     lsTransfer(A, B);
  1149.     if Width > B^.dLength then exit;
  1150.     if Width < B^.Length then begin
  1151.       B^.Length := Width;
  1152.       exit;
  1153.       end;
  1154.     W1 := Width - ((Width - B^.Length) shr 1);
  1155.     lsLeftPadCh(B, Ch, W1, B);
  1156.     lsPadCh(B, Ch, Width, B);
  1157.     end; {lsCenterCh}
  1158.  
  1159. function lsCenterChF(A : LongString; Ch : Char; Width : word) : LongString;
  1160.   {-Return a LongString centered in a LongString of Ch with specified width}
  1161.   var
  1162.     ThisLs  : LongString;
  1163.   begin
  1164.     ThisLs := NextInRing(Width);
  1165.     lsCenterCh(A, Ch, Width, ThisLs);
  1166.     lsCenterChF := ThisLs;
  1167.     end; {lsCenterChF}
  1168.  
  1169. procedure lsCenter(A : LongString; Width : word; B : LongString);
  1170.   {-Return a LongString centered in a LongString of blanks with specified width}
  1171.   begin
  1172.     lsCenterCh(A, Blank, Width, B);
  1173.     end; {lsCenter}
  1174.  
  1175. function lsCenterF(A : LongString; Width : word)  : LongString;
  1176.   {-Return a LongString centered in a LongString of blanks with specified width}
  1177.   var
  1178.     ThisLs  : LongString;
  1179.   begin
  1180.     ThisLs := NextInRing(Width);
  1181.     lsCenterCh(A, Blank, Width, ThisLs);
  1182.     lsCenterF := ThisLs;
  1183.     end; {lsCenterF}
  1184.  
  1185. procedure lsIon;
  1186.   {-Has the same effect with respect to lsReadLn, lsWriteLn as the $I+
  1187.     compiler has with respect to normal I/O operations, except that
  1188.     the reported error address is meaningless.}
  1189.   begin
  1190.     lsIoCheck := true;
  1191.     end; {lsIon}
  1192.  
  1193. procedure lsIoff;
  1194.   {-Has the same effect with respect to lsReadLn, lsWriteLn as the $I-
  1195.     compiler has with respect to normal I/O operations, except that
  1196.     the reported error address is meaningless.}
  1197.   begin
  1198.     lsIoCheck := false;
  1199.     end; {lsIoff}
  1200.  
  1201. procedure SetIoRes;
  1202.   begin
  1203.     lsIoRes := IoResult;
  1204.     if lsIoCheck and (lsIoRes <> 0) then
  1205.       RunError(lsIoRes);
  1206.     end; {SetIoRes}
  1207.  
  1208. procedure CheckIoRes;
  1209.   begin
  1210.     if (lsIoRes <> 0) then
  1211.       RunError(lsIoRes);
  1212.     end;
  1213.  
  1214. function lsIoResult : word;
  1215.   {-Returns the value of IoResult resulting from the last lsReadLn or
  1216.     lsWriteLn. NOTE: You MUST use lsIoResult for checking lsReadLn,
  1217.     lsWriteLn. If you call IoResult instead, you will always get a 0
  1218.     return.}
  1219.   begin
  1220.     lsIoResult := lsIoRes;
  1221.     lsIoRes := 0;
  1222.     end;
  1223.  
  1224. {$I-}
  1225. procedure lsReadLn(var F  : text; A : LongString);
  1226.   {-Reads a LongString from a text file. Returns the value of IoResult as
  1227.    the function value.}
  1228.   var
  1229.     S   : string;
  1230.     W1  : word;
  1231.   begin
  1232.     CheckIoRes;
  1233.     A^.Length := 0;
  1234.     while (not eoln(F)) and (A^.dLength > A^.Length) do begin
  1235.       Read(F, S);
  1236.       SetIoRes;
  1237.       if lsIoRes <> 0 then begin
  1238.         exit;
  1239.         end;
  1240.       lsConcatStr2Ls(A, S, A);
  1241.       end; {while}
  1242.     ReadLn(F);
  1243.     SetIoRes;
  1244.     end; {lsReadLn}
  1245.  
  1246. procedure lsWriteLn(var F  : text; A : LongString);
  1247.   {-Writes a LongString to a text file. Returns the value of IoResult as
  1248.    the function value.}
  1249.   var
  1250.     S       : string;
  1251.     W1,
  1252.     W2,
  1253.     Q,
  1254.     R       : word;
  1255.     ThisLs  : LongString;
  1256.   begin
  1257.     CheckIoRes;
  1258.     if not lsInit(ThisLs, A^.Length) then exit;
  1259.     lsTransfer(A, ThisLs);
  1260.     Q := A^.Length div $FF;
  1261.     R := A^.Length mod $FF;
  1262.     for W1 := 1 to Q do begin
  1263.       Write(F, lsLongString2Str(ThisLs));
  1264.       SetIoRes;
  1265.       Flush(F);
  1266.       SetIoRes;
  1267.       if lsIoRes <> 0 then begin
  1268.         lsDispose(ThisLs);
  1269.         exit;
  1270.         end;
  1271.       lsDelete(ThisLs, 1, $FF, ThisLs);
  1272.       end; {for W1}
  1273.     WriteLn(F, lsLongString2Str(ThisLs));
  1274.     SetIoRes;
  1275.     Flush(F);
  1276.     SetIoRes;
  1277.     lsDispose(ThisLs);
  1278.     end; {lsWriteLn}
  1279. {$I+}
  1280.  
  1281. begin {Initialization}
  1282.   if RingSize > MaxRingSize then begin
  1283.     WriteLn('RingSize (',RingSize,') > MaxRingSize (',MaxRingSize,')');
  1284.     WriteLn('Resetting to ',MaxRingSize);
  1285.     RingSize := MaxRingSize;
  1286.     end;
  1287.   for RingPtr := 0 to RingSizeM1 do
  1288.     Ring[RingPtr] := nil;
  1289.   RingPtr := -1;
  1290.   end.
  1291.